package com.teamone.addressbook.Control;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.util.Vector;

import com.teamone.addressbook.View.*;
import com.teamone.addressbook.Model.*;
import com.teamone.timeserver.Client;

public class AddressCtrl {

	// Views
	private AddressBook addressbook;
	private ModifyDialog modifydialog;
	
	// Models
	private RegisterAddrEty registeraddr;
	private ModifyAddrEty modifyaddr;
	private RetrieveAddrEty retrieveaddr;
	private DeleteAddrEty deleteaddr;
	private UpdateTimeLabelThread t;
	
	public static Vector<String> columnlist = new Vector<String>();
	
	public AddressCtrl()
	{
		for (int i = 0; i < Address.Column_Names.length; i++)
		{
			columnlist.add(Address.Column_Names[i]);
		}
	}
	
	public void addView(Object o) throws ClassNotFoundException
	{
		if (o instanceof AddressBook)
		{
			this.addressbook = (AddressBook)o;
			
			this.addressbook.addMainMenuWindowListener(new MainMenuWindowListener());
			this.addressbook.addMainMenuActionListener(new MainMenuActionListener());
			this.addressbook.addTableMouseListener(new TableMouseListener());
			
			this.addressbook.updateTable(this.retrieveaddr.retrieveAddress());
			
			t = new UpdateTimeLabelThread("t");
			
			t.start();
		}
		
		else if (o instanceof ModifyDialog)
		{
			this.modifydialog = (ModifyDialog)o;
			
			this.modifydialog.addModifyDialogActionListener(new ModifyDialogActionListener());
		}
		
		else
		{
			throw new ClassNotFoundException();
		}
	}
	
	public void addModel(Object o) throws ClassNotFoundException
	{
		if (o instanceof RegisterAddrEty)
		{
			this.registeraddr = (RegisterAddrEty)o;
		}
		
		else if (o instanceof ModifyAddrEty)
		{
			this.modifyaddr = (ModifyAddrEty)o;
		}
		
		else if (o instanceof RetrieveAddrEty)
		{
			this.retrieveaddr = (RetrieveAddrEty)o;
		}
		
		else if (o instanceof DeleteAddrEty)
		{
			this.deleteaddr = (DeleteAddrEty)o;
		}
		
		else
		{
			throw new ClassNotFoundException();
		}
	}
	
	public Address getSelectedAddress()
	{
		Address adr = null;
		
		int id = addressbook.getSelectedID();
		
		if (id >= 0)
		{
			adr = retrieveaddr.retrieveAddress(id);
		}
		
		return adr;
	}
	
	class MainMenuWindowListener implements WindowListener
	{

		@Override
		public void windowActivated(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowClosed(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowClosing(WindowEvent arg0) {
			
			t.stopThread();
			System.exit(0);
		}

		@Override
		public void windowDeactivated(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowDeiconified(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowIconified(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void windowOpened(WindowEvent arg0) {
			// TODO Auto-generated method stub
			
		}
		
	}
	
	class TableMouseListener implements MouseListener
	{

		@Override
		public void mouseClicked(MouseEvent arg0) {
			
			if (arg0.getClickCount() == 2)
			{
				Address adr = getSelectedAddress();
				
				if (adr != null)
				{
					if (deleteaddr.deleteAddress(adr) > 0)
					{
						addressbook.updateTable(retrieveaddr.retrieveAddress());
					}
				}
			}
		}

		@Override
		public void mouseEntered(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseExited(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mousePressed(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void mouseReleased(MouseEvent arg0) {
			// TODO Auto-generated method stub
			
		}
		
	}
	
	class MainMenuActionListener implements ActionListener
	{

		@Override
		public void actionPerformed(ActionEvent e)
		{
			String command = e.getActionCommand();
			
			if (command.equals("Exit"))
			{
				t.stopThread();
				
				System.exit(0);
			}
			
			else if (command.equals("View"))
			{
				Address adr = getSelectedAddress();

				if (adr != null)
				{
					if (modifydialog != null)
					{
						modifydialog.updateView(adr);
						modifydialog.setMode("View");
					}
				}
			}
			
			else if (command.equals("Modify"))
			{
				Address adr = getSelectedAddress();

				if (adr != null)
				{
					if (modifydialog != null)
					{
						modifydialog.updateView(adr);
						modifydialog.setMode("Modify");
					}
				}
			}
			
			else if (command.equals("Register"))
			{
				if (modifydialog != null)
				{
					modifydialog.clearView();
					modifydialog.setMode("Register");
				}
			}
			
			else if (command.equals("Delete"))
			{
				Address adr = getSelectedAddress();
				
				if (adr != null)
				{
					if (deleteaddr.deleteAddress(adr) > 0)
					{
						addressbook.updateTable(retrieveaddr.retrieveAddress());
					}
				}
			}
		}
	}
	
	class ModifyDialogActionListener implements ActionListener
	{
		@Override
		public void actionPerformed(ActionEvent e) {
			
			String command = e.getActionCommand();
			
			if (command.equals("Okay"))
			{
				String mode = modifydialog.getMode();
				
				if (mode.equals("Modify"))
				{
					if (modifyaddr.modifyAddress(modifydialog.getAddress()) > 0)
					{
						addressbook.updateTable(retrieveaddr.retrieveAddress());
					}
				}
				
				else if (mode.equals("Register"))
				{
					registeraddr.registerAddress(modifydialog.getAddress());
					addressbook.updateTable(retrieveaddr.retrieveAddress());
				}
				
				modifydialog.setVisible(false);
			}
			
			else if (command.equals("Cancel"))
			{
				modifydialog.setVisible(false);
			}
		}
	}
	
	class UpdateTimeLabelThread extends Thread
	{
		private volatile boolean shouldstop = false;
		
		UpdateTimeLabelThread()
		{
		
		}
		
		UpdateTimeLabelThread(String threadName)
		{
			super(threadName);
		}
		
		public void stopThread()
		{
			shouldstop = true;
		}
		
		public void run()
		{
			String now = null;
			
			while (!shouldstop)
			{
				//System.out.println("shouldstop:"+shouldstop);
				
				try
				{
					now = Client.getTimeFromServer("localhost");
				}
				catch (IOException e)
				{
					System.out.println(e.getMessage());
					return;
				}
				
				if (addressbook != null) addressbook.updateTimeLabel(now);
						
				try
				{
					sleep(1000);
				}
				catch (InterruptedException e)
				{
					System.out.println(e.getMessage());
					return;
				}
			}
		}
	}
}
